package com.bcbim.api_web.health.controller;

import com.alibaba.fastjson.JSONArray;
import com.bcbim.api_web.sys.redis.MyRedisService;
import com.bcbim.authentication_interface.util.AuthUtil;
import com.bcbim.common.response.annotation.Translate;
import com.bcbim.common.response.vo.ReturnMsg;
import com.bcbim.common.response.vo.ReturnPageMsg;
import com.bcbim.common.sys.Code;
import com.bcbim.common.sys.Constant;
import com.bcbim.common.sys.ParamException;
import com.bcbim.common.util.LngLonUtil;
import com.bcbim.common.util.ParamCheck;
import com.bcbim.smart_water_interface.health.bo.UpdateFlawLatLonBO;
import com.bcbim.smart_water_interface.health.dto.*;
import com.bcbim.smart_water_interface.health.service.HealthService;
import com.bcbim.smart_water_interface.health.vo.FlawLocationVO;
import com.bcbim.smart_water_interface.health.vo.HealthInfoVO;
import com.bcbim.smart_water_interface.health.vo.HealthMaintenanceVO;
import com.bcbim.smart_water_interface.health.vo.HealthVO;
import com.bcbim.smart_water_interface.maintenance.service.MaintenanceService;
import com.bcbim.smart_water_interface.maintenance.vo.MaintenanceVO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.gavaghan.geodesy.Ellipsoid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description: 健康监测controller
 * @Author: ye
 * @Date: 2021/8/27
 * @Version: V1.0
 **/
@RestController
@RequestMapping("/health")
public class HealthController {

    @Reference(protocol = "dubbo", group = "health", version = "1.0.0")
    private HealthService healthServiceImpl;

    @Reference(protocol = "dubbo", group = "maintenance", version = "1.0.0")
    private MaintenanceService maintenanceServiceImpl;

    @Autowired
    private MyRedisService reidsService;

    /**
     * @Description: 健康检测列表查询
     * @Param: ListHealthDto
     * @Return: ReturnPageMsg
     * @Author: ye
     * @Date: 2021/8/27
     */
    @Translate
    @PostMapping("listHealth")
    public ReturnPageMsg listHealth(ListHealthDTO query) {
        List<HealthVO> list = new ArrayList<>();
        int total = healthServiceImpl.countHealth(query);
        if (total > 0) {
            query.setStart((query.getPageNum() - 1) * query.getPageSize());
            list = healthServiceImpl.listHealth(query);
        }
        return ReturnPageMsg.consSuccess(total, list);
    }

    /**
     * @Description: 缺陷种类查询
     * @Param: defectType 缺陷类型
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/8/27
     */
    @PostMapping("getDefect")
    public ReturnMsg getDefect(String defectType) {
        try {
            ParamCheck.stringNotEmpty(defectType, 1);
        } catch (ParamException e) {
            return ReturnMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        List<Code> defects = healthServiceImpl.getDefect(defectType);
        return ReturnMsg.consSuccess(defects);
    }

    /**
     * @Description: 查询健康检测详情
     * @Param: healthId
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/8/27
     */
    @Translate
    @PostMapping("getHealthInfo")
    public ReturnMsg getHealthInfo(String healthId) {
        try {
            ParamCheck.idCheck(healthId);
        } catch (ParamException e) {
            return ReturnMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        HealthInfoVO healthInfoVo = healthServiceImpl.getHealthInfoByHealthId(healthId);
        if (ObjectUtils.isEmpty(healthInfoVo)) {
            return ReturnMsg.consFail();
        }
        healthInfoVo.setArrFlaw(healthServiceImpl.getFlawInfoByHealthId(healthId));
        healthInfoVo.setFunctionalDefect(healthServiceImpl.getHealthDefect(healthId, Constant.FUNCTIONAL_DEFECT));
        healthInfoVo.setStructuralDefects(healthServiceImpl.getHealthDefect(healthId, Constant.STRUCTURAL_DEFECT));

        if (ObjectUtils.isNotEmpty(healthInfoVo.getStartLatitude()) && ObjectUtils.isNotEmpty(healthInfoVo.getStartLongitude()) &&
                ObjectUtils.isNotEmpty(healthInfoVo.getEndLatitude()) && ObjectUtils.isNotEmpty(healthInfoVo.getEndLongitude())) {
            double distance = LngLonUtil.getDistanceMeter(healthInfoVo.getStartLatitude(), healthInfoVo.getStartLongitude(),
                    healthInfoVo.getEndLatitude(), healthInfoVo.getEndLongitude(), Ellipsoid.WGS84);
            healthInfoVo.setDistance(distance);
        }
        return ReturnMsg.consSuccess(healthInfoVo);
    }

    /**
     * @Description: 健康检测的养护数据表
     * @Param: HealthMaintenanceDTO
     * @Return: ReturnPageMsg
     * @Author: ye
     * @Date: 2021/8/30
     */
    @Translate
    @PostMapping("listMaintenance")
    public ReturnPageMsg listMaintenance(HealthMaintenanceDTO query) {
        try {
            ParamCheck.pageNumCheck(query.getPageNum(), query.getPageSize());
            ParamCheck.idCheck(query.getLineId());
        } catch (ParamException e) {
            return ReturnPageMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        List<HealthMaintenanceVO> list = new ArrayList<>();

        int total = maintenanceServiceImpl.countHealthMaintenance(query);
        if (total > 0) {
            query.setStart((query.getPageNum() - 1) * query.getPageSize());
            list = maintenanceServiceImpl.listHealthMaintenance(query);
        }
        return ReturnPageMsg.consSuccess(total, list);
    }

    /**
     * @Description: 更新缺陷位置信息
     * @Param:
     * @Return:
     * @Author: ye
     * @Date: 2021/9/2
     */
    @PostMapping("updateFlawLocation")
    public ReturnMsg updateFlawLocation() {
        List<UpdateFlawLatLonBO> list = healthServiceImpl.getUpdateFlawLatLon();
        List<UpdateFlawLatLonDTO> update = new ArrayList<>();

        for (UpdateFlawLatLonBO bo : list) {
            UpdateFlawLatLonDTO dto = new UpdateFlawLatLonDTO();
            dto.setFlawId(bo.getFlawId());
            double angle = LngLonUtil.getAngle(bo.getStartLat(),bo.getStartLon(),bo.getEndLat(),bo.getEndLon());
            double[] latlon = LngLonUtil.computerThatLonLat(bo.getStartLat(), bo.getStartLon(), angle, Double.parseDouble(bo.getFlawLocation().replace("m", "")));
            dto.setLatitude(latlon[0]);
            dto.setLongitude(latlon[1]);
            update.add(dto);
        }
        healthServiceImpl.updateFlawLocation(update);
        return ReturnMsg.consSuccess();
    }

    /**
     * @Description: 查询地图上缺陷位置信息
     * @Param: FlawLocationDTO
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/9/2
     */
    @PostMapping("listFlawLocation")
    public ReturnMsg listFlawLocation(FlawLocationDTO query) {
        if ((ObjectUtils.isEmpty(query.getStructuralDefectId()) || query.getStructuralDefectId().length == 0) &&
        (ObjectUtils.isEmpty(query.getFunctionalDefectId()) || query.getFunctionalDefectId().length == 0) &&
        (ObjectUtils.isEmpty(query.getFunctionalDefectLevels()) || query.getFunctionalDefectLevels().length == 0) &&
        (ObjectUtils.isEmpty(query.getStructuralDefectLevels()) || query.getStructuralDefectLevels().length == 0)
        ) {
            return ReturnMsg.consSuccess();
        }
        List<FlawLocationVO> list = healthServiceImpl.listFlawLocation(query);
        return ReturnMsg.consSuccess(list);
    }

    /**
     * @Description: 查询管线缺陷数据
     * @Param: lineId
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/9/16
     */
    @Translate
    @PostMapping("getLineHealthInfo")
    public ReturnMsg getLineHealthInfo(String lineId) {
        try {
            ParamCheck.idCheck(lineId);
        } catch (ParamException e) {
            return ReturnMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        HealthInfoVO lineInfo = healthServiceImpl.getHealthByLineId(lineId);
        if (ObjectUtils.isNotEmpty(lineInfo)) {
            lineInfo.setArrFlaw(healthServiceImpl.getFlawInfoByHealthId(lineInfo.getHealthId()));
            lineInfo.setFunctionalDefect(healthServiceImpl.getHealthDefect(lineInfo.getHealthId(), Constant.FUNCTIONAL_DEFECT));
            lineInfo.setStructuralDefects(healthServiceImpl.getHealthDefect(lineInfo.getHealthId(), Constant.STRUCTURAL_DEFECT));

            if (ObjectUtils.isEmpty(lineInfo)) {
                return ReturnMsg.consFail("暂无管线信息");
            }
            if (ObjectUtils.isNotEmpty(lineInfo.getStartLatitude()) && ObjectUtils.isNotEmpty(lineInfo.getStartLongitude()) &&
                    ObjectUtils.isNotEmpty(lineInfo.getEndLatitude()) && ObjectUtils.isNotEmpty(lineInfo.getEndLongitude())) {
                double distance = LngLonUtil.getDistanceMeter(lineInfo.getStartLatitude(), lineInfo.getStartLongitude(),
                        lineInfo.getEndLatitude(), lineInfo.getEndLongitude(), Ellipsoid.WGS84);
                lineInfo.setDistance(distance);
                lineInfo.setFlawLocations(healthServiceImpl.getFlawLocationByLineId(lineId));
            }
        }
        return ReturnMsg.consSuccess(lineInfo);
    }

    /**
     * @Description: 添加健康监测添加
     * @Param: healthId
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/10/29
     */
    @PostMapping("addHealthDownloadSet")
    public ReturnMsg addHealthDownloadSet(String healthId) {
        try {
            ParamCheck.idCheck(healthId);
        } catch (ParamException e) {
            return ReturnMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        String healthToken = AuthUtil.getHealthToken();
        JSONArray lineJsonArray = (JSONArray) reidsService.get(healthToken);
        Set<String> setHealthId = lineJsonArray == null ? new HashSet<>() : new HashSet<>(lineJsonArray.toJavaList(String.class));
        setHealthId.add(healthId);
        reidsService.set(healthToken, setHealthId, Constant.PERMISSION_EXPIRATION_TIME);
        return ReturnMsg.consSuccess("添加成功");
    }

    /**
     * @Description: 添加全部
     * @Param:
     * @Return:
     * @Author: ye
     * @Date: 2021/10/29
     */
    @PostMapping("addAllHealthDownloadSet")
    public ReturnMsg addAllHealthDownloadSet(ListHealthDTO query) {
        String healthToken = AuthUtil.getHealthToken();
        JSONArray lineJsonArray = (JSONArray) reidsService.get(healthToken);
        Set<String> setHealthId = lineJsonArray == null ? new HashSet<>() : new HashSet<>(lineJsonArray.toJavaList(String.class));
        List<String> arrHealthId = healthServiceImpl.getHealthId(query);
        setHealthId.addAll(arrHealthId);
        reidsService.set(healthToken, setHealthId, Constant.PERMISSION_EXPIRATION_TIME);
        return ReturnMsg.consSuccess("添加成功");
    }

    /**
     * @Description: 清空下载集
     * @Param:
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/10/29
     */
    @PostMapping("cleanHealthDownloadSet")
    public ReturnMsg cleanHealthDownloadSet() {
        String healthToken = AuthUtil.getHealthToken();
        reidsService.delete(healthToken);
        return ReturnMsg.consSuccess("已清空");
    }

    /**
     * @Description: 下载集列表
     * @Param:
     * @Return:
     * @Author: ye
     * @Date: 2021/10/29
     */
    @Translate
    @PostMapping("listDownloadSet")
    public ReturnPageMsg listDownloadSet(ListDownloadSetHealthDTO query) {
        try {
            ParamCheck.pageNumCheck(query.getPageNum(), query.getPageSize());
        } catch (ParamException e) {
            return ReturnPageMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        List<HealthVO> list = new ArrayList<>();

        String healthToken = AuthUtil.getHealthToken();
        JSONArray lineJsonArray = (JSONArray) reidsService.get(healthToken);
        if (lineJsonArray == null || lineJsonArray.size() == 0) {
            return ReturnPageMsg.consSuccess(0, list);
        }

        query.setArrHealthId(lineJsonArray.toJavaList(String.class));
        int total = healthServiceImpl.countHealthDownloadSet(query);
        if (total > 0) {
            query.setStart((query.getPageNum() - 1) * query.getPageSize());
            list = healthServiceImpl.listHealthDownloadSet(query);
        }
        return ReturnPageMsg.consSuccess(total, list);
    }

    /**
     * @Description: 删除下载集
     * @Param: healthId
     * @Return: ReturnMsg
     * @Author: ye
     * @Date: 2021/10/29
     */
    @PostMapping("removeDownloadSetHealthId")
    public ReturnMsg removeDownloadSetHealthId(String healthId) {
        try {
            ParamCheck.idCheck(healthId);
        } catch (ParamException e) {
            return ReturnMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        String healthToken = AuthUtil.getHealthToken();
        JSONArray setHealthId = (JSONArray) reidsService.get(healthToken);
        setHealthId.remove(healthId);
        reidsService.set(healthToken, setHealthId, Constant.PERMISSION_EXPIRATION_TIME);
        return ReturnMsg.consSuccess("删除成功");
    }

    /**
     * @Description 查询管点详情
     * @Author XueHao
     * @Date 2021/8/26
     * @return ReturnMsg
     */
    @Translate
    @PostMapping("/getMaintenance")
    public ReturnMsg getMaintenance(String maintenanceId){
        //参数校验
        try {
            ParamCheck.idCheck(maintenanceId);
        } catch (ParamException e) {
            return ReturnMsg.consFail(ParamException.PARAMETER_ERROR);
        }
        //查询数据库
        MaintenanceVO maintenanceVO = maintenanceServiceImpl.getMaintenance(maintenanceId);
        return ReturnMsg.consSuccess(maintenanceVO);
    }
}
